package com.xrh.xdemo.service.service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import com.xrh.core.exceptions.BusinessException;
import com.xrh.core.utils.XAssert;
import com.xrh.xdemo.api.constants.LoginConstants;
import com.xrh.xdemo.api.request.common.LoginRequest;
import com.xrh.xdemo.service.entity.SysUserEntity;
import com.xrh.xdemo.service.utils.LoginUtils;
import com.xrh.xdemo.service.utils.LoginValidCodeUtils;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWTPayload;
import cn.hutool.jwt.JWTUtil;

@Service
public class LoginService {
	
	@Resource
	SysUserService sysUserService;
	
	//生成admin永久token
	public static void main(String[] args) {
		
		//eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJTWVNfVVNFUl9JTkZPIiwibmJmIjoxNzAyMDI4MjA0LCJleHAiOjM4NDk1MTE4NTEsImlhdCI6MTcwMjAyODIwNCwiU1lTX1VTRVJfSURfS0VZIjotMX0.njKZL4gtjN2Msmau-ewLIgKblUlHAMwLPX-OUs-Ow-0
		
		//多少秒后过期
		int expireSecond = Integer.MAX_VALUE;
		
		DateTime now = DateTime.now();
		
		//过期时间
		DateTime expireDate = now.offsetNew(DateField.SECOND, expireSecond);
		
		//载和信息
		Map<String , Object> payload = new HashMap<String, Object>();
		
		//签发时间
		payload.put(JWTPayload.ISSUED_AT , now);
		
		//过期时间
		payload.put(JWTPayload.EXPIRES_AT , expireDate);
		
		//生效时间
		payload.put(JWTPayload.NOT_BEFORE , now);
		
		//主题
		payload.put(JWTPayload.SUBJECT , LoginConstants.JWT_LOGIN_USER_SUBJECT);
		
		//存入数据
		payload.put(LoginConstants.JWT_LOGIN_USER_ID_KEY, LoginConstants.JWT_LOGIN_SYS_ACCOUNT_ID);
		
		String token = JWTUtil.createToken(payload, LoginConstants.JWT_LOGIN_USER_KEY.getBytes());
		
		System.out.println(token);
	}
	
	/**
	 * @function 登录
	 * @author 肖荣辉
	 * @date 2023年12月8日
	 * @return 返回token
	*/
	public String login(LoginRequest loginRequest) {
		
		//验证验证码 , 如果需要的话
		LoginValidCodeUtils.validErrorValidCode(loginRequest.getErrorValidCode());
        
		//参数
		String account = loginRequest.getAccount();
		String password = loginRequest.getPassword();
		
		//系统配置的账号密码
		Environment environment = SpringUtil.getBean(Environment.class);
		
		//系统账号密码
		String sysAccount = environment.getProperty("sys.account");
		String sysPassword = environment.getProperty("sys.password");
		
		//是否是超级管理员
		boolean isAdmin = sysAccount.equals(loginRequest.getAccount());
		
		//用户id
		Long userId = LoginConstants.JWT_LOGIN_SYS_ACCOUNT_ID;
		
		//超级管理员
		if(isAdmin) {
			
			//校验密码 , 如果错误 , 增加输错错误次数
			checkPasswordAndAddInputErrorTimes(SecureUtil.md5(sysPassword) , password);
			
		}else {
			
			SysUserEntity entity = sysUserService.findSysUserByAccount(account);
			
			XAssert.isTrue(entity != null, "账号或密码不正确");
			
			//校验密码 , 如果错误 , 增加输错错误次数
			checkPasswordAndAddInputErrorTimes(entity.getPassword(), password);
			
			XAssert.isTrue(entity.getEnable() == 1, "当前账号已禁用 , 请联系管理员");
			
			userId = entity.getId();
			
			//更新用户登录时间
			entity.setLastLoginTime(new Date());
			
			//压缩登录信息 , 放缓存里
	        String loginInfo = Base64.encode(ZipUtil.gzip(JSONUtil.toJsonStr(sysUserService.findSysUserDetailById(entity.getId())), "utf-8"));
	        
	        entity.setLoginInfo(loginInfo);
	        
			sysUserService.updateById(entity);
		}
		
		//登录成功 , 清空登录次数和验证码
		LoginValidCodeUtils.clearErrorValidCodeAndTimes();
		
		//多少秒后过期
		int expireSecond = LoginConstants.JWT_LOGIN_USER_EXPIRE_SECOND;
		
		DateTime now = DateTime.now();
		
		//过期时间
		DateTime expireDate = now.offsetNew(DateField.SECOND, expireSecond);
		
		//载和信息
		Map<String , Object> payload = new HashMap<String, Object>();
		
		//签发时间
		payload.put(JWTPayload.ISSUED_AT , now);
		
		//过期时间
		payload.put(JWTPayload.EXPIRES_AT , expireDate);
		
		//生效时间
		payload.put(JWTPayload.NOT_BEFORE , now);
		
		//主题
		payload.put(JWTPayload.SUBJECT , LoginConstants.JWT_LOGIN_USER_SUBJECT);
		
		//存入数据
		payload.put(LoginConstants.JWT_LOGIN_USER_ID_KEY, userId);
		
		String token = JWTUtil.createToken(payload, LoginConstants.JWT_LOGIN_USER_KEY.getBytes());
		
		//登录成功设置下数据
		LoginUtils.setLoginInfoToRequest(sysUserService.findSysUserDetailById(userId));
		
		return token;
	}
	
	/**
	 * @function 校验密码 , 如果错误 , 增加输错错误次数
	 * @param dbPassword
	 * @param submitPassword
	 * @author 肖荣辉
	 * @date 2023年12月21日
	*/
	public void checkPasswordAndAddInputErrorTimes( String dbPassword , String submitPassword) {
		
		if(dbPassword.equals(submitPassword))
			return;
		
		LoginValidCodeUtils.addLoginErrorTimes();
		
		throw new BusinessException("账号或密码不正确");
		
	}
	
}
